package org.fin.minicat.compile;

import javax.tools.*;
import java.io.File;
import java.io.IOException;

@SuppressWarnings("ALL")
public class Compiler {

  private String sourceRoot;

  private JavaCompiler compiler;

  private StandardJavaFileManager fileManager;


  public Compiler(String sourceRoot) {
    this.sourceRoot = sourceRoot;
    this.compiler = ToolProvider.getSystemJavaCompiler();
    this.fileManager = compiler.getStandardFileManager(null, null, null);
  }

  /**
   * 进行编译
   */
  public void compile() {

    File sourceRootDir = new File(sourceRoot);
    if (sourceRootDir.exists() && sourceRootDir.isDirectory()) {
      // 编译根目录下的java文件
      compile(sourceRoot);

      // 递归编译所有子目录的文件
      File[] subDirs = sourceRootDir.listFiles(File::isDirectory);
      for (File subDir : subDirs) {
        compile(subDir.getAbsolutePath());
        subDir.listFiles(File::isDirectory);
      }
    }
  }

  /**
   * 编译指定目录和所有子目录的.java文件，并在原目录下生成同名的.class文件
   * @param dirPath 存放要编译的java文件的绝对路径
   */
  private void compile(String dirPath) {
    File dir = new File(dirPath);
    File[] javaFiles = dir.listFiles((file, name) -> name.endsWith(".java"));
    Iterable<? extends JavaFileObject> units = fileManager.getJavaFileObjects(javaFiles);
    JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, units);
    task.call();

    // 递归编译所有子目录
    for (File subDir : dir.listFiles(File::isDirectory)) {
      compile(subDir.getAbsolutePath());
    }
  }

  public void close() throws IOException {
    fileManager.close();
  }
}
